/*
 * Copyright (C) Siemens AG, 2018
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *  
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include <assert.h>
#include <errno.h>
#include <dlfcn.h>
#include <error.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

static void *my_dlopen(char *name)
{
	void *handle;
	char buf[PATH_MAX];
	int flags = RTLD_LAZY|RTLD_GLOBAL;

	handle = dlopen(name, flags);
	if (!handle) {
		// no matter what the error was (errno not set) try it again
		// with absolute path, the first one is there to enable
		// LD_LIBRARY_PATH
		snprintf(buf, PATH_MAX, "%s/%s", XENO_TEST_DIR, name);
		handle = dlopen(buf, flags);
		if (!handle)
			error(1, errno, dlerror());
	}
	return handle;
}

static int my_dlcall(char *lname, char *fname, void **handle)
{
	int (*func)(void);
	char *errstr;

	*handle = my_dlopen(lname);
	func = dlsym(*handle, fname);
	errstr = dlerror();
	if (errstr)
		error(1, errno, "%s", errstr);

	return func();
}

int main(int argc, char *const argv[])
{
	void *handlea, *handlep;
	int ret;

	ret = my_dlcall("libalchemy-test.so", "libalchemy_func", &handlea);
	if (ret)
		error(1, errno, "libalchemy_func: %s", strerror(-ret));

	ret = my_dlcall("libposix-test.so", "libposix_func", &handlep);
	if (ret)
		error(1, errno, "libposix_func: %s", strerror(-ret));

	return 0;
}
